This show a simple example how to load a single image.
It uses imctools: https://github.com/BodenmillerGroup/imctools and bbwidgets: https://github.com/BodenmillerGroup/bbwidgets
Further it shows a more complex example, how to load a folder containing IMC ome folders & using all the metadata to lable the acquisitions.
from imctools.io import ometiffparser
import bbwidgets
fn_ome = '/home/vitoz/Data/Analysis/201805_cp3_processing/ometiff/20170906_FluidigmONfinal_SE/20170906_FluidigmONfinal_SE_s0_p2_r3_a3_ac.ome.tiff'
imc_ac = ometiffparser.OmetiffParser(fn_ome).get_imc_acquisition()
bbwidgets.view_multichannel([imc_ac.data], channel_names=imc_ac.channel_labels)
import bbwidgets
import pathlib
import pandas as pd
import numpy as np
import re
from imctools.io import ometiffparser
from imctools.scripts import exportacquisitioncsv
import imctools.io.mcdxmlparser as mcdmeta
class variables:
"""
This contains variables that should not be changed
"""
COL_FN = 'filename'
COL_PATH = 'path'
COL_IMCAC = 'imc_ac'
COL_VALIDAC = 'has_all_channels'
COL_IMGS = 'images'
COL_ACSESSION = exportacquisitioncsv.COL_ACSESSION
COL_SLIDEID = mcdmeta.SLIDEID
COL_PANORAMAID = mcdmeta.PANORAMAID
COL_ACQUISITIONROIID = mcdmeta.ACQUISITIONROIID
COL_ACQUISITIONID = mcdmeta.ACQUISITIONID
COL_PANORAMA = mcdmeta.PANORAMA
COL_ACQUISITIONROI = mcdmeta.ACQUISITIONROI
COL_ACQUISITION = mcdmeta.ACQUISITION
re_fn_meta = re.compile(f'(?P<{COL_ACSESSION}>.*)_s(?P<{COL_SLIDEID}>[0-9]+)_p(?P<{COL_PANORAMAID}>[0-9]+)_r(?P<{COL_ACQUISITIONROIID}>[0-9]+)_a(?P<{COL_ACQUISITIONID}>[0-9]+)_ac.*')
meta_types = {COL_ACSESSION: str,
COL_SLIDEID: int,
COL_PANORAMAID: int,
COL_ACQUISITIONROIID: int,
COL_ACQUISITIONID: int}
V = variables
class configuration:
"""
This contains configurations that likely need to be changed/adapted
"""
# the folder containing other ome folders
fol_ome = pathlib.Path('/home/vitoz/Data/Analysis/201805_cp_segmentation_example/ometiff/')
C = configuration
Memory map all the acquisitions
dat_acs = pd.DataFrame({V.COL_PATH: list(C.fol_ome.glob('*/*.ome.tiff'))})
dat_acs[V.COL_IMCAC] = dat_acs[V.COL_PATH].map(lambda fn: ometiffparser.OmetiffParser(fn).get_imc_acquisition())
Get the metadata
-> This loads all the metadata csv from the ome folder
dat_acmeta = exportacquisitioncsv._read_and_concat(C.fol_ome,suffix=f'_{mcdmeta.ACQUISITION}_meta.csv',idname=mcdmeta.ACQUISITIONID).rename(columns={mcdmeta.DESCRIPTION: mcdmeta.ACQUISITION})
dat_panometa = exportacquisitioncsv._read_and_concat(C.fol_ome,suffix=f'_{mcdmeta.PANORAMA}_meta.csv',idname=mcdmeta.PANORAMAID).rename(columns={mcdmeta.DESCRIPTION: mcdmeta.PANORAMA})
dat_roimeta = exportacquisitioncsv._read_and_concat(C.fol_ome,suffix=f'_{mcdmeta.ACQUISITIONROI}_meta.csv',idname=mcdmeta.ACQUISITIONROIID).rename(columns={mcdmeta.DESCRIPTION: mcdmeta.ACQUISITIONROI})
Parse the metadata from the filenames
def split_names(x, re_comp):
c = re_comp
m = c.match(x)
g = m.groups()
return pd.Series({l: g[i-1] for l, i in c.groupindex.items()}, name=x.index)
dat_acs[V.COL_FN] = dat_acs[V.COL_PATH].map(lambda x: x.stem)
dat_acs = dat_acs.join(dat_acs[V.COL_FN].apply(split_names, re_comp=V.re_fn_meta))
dat_acs = dat_acs.astype(V.meta_types)
def get_img_from_imcac(imcac, metals):
"""
A helper function to get the image stacks with the right metals
"""
return [imcac.get_img_by_metal(m) for m in metals]
Determine a reference acquisition to choos the channel labels from
ref_idx = 8
ref_ac = dat_acs[V.COL_IMCAC][ref_idx]
metals = ref_ac.channel_metals
# derive nicer labels
channel_labels = [f'{l} - {m}' for l, m in zip(ref_ac.channel_labels, ref_ac.channel_metals)]
print(f'Reference Acquisition: {ref_ac.image_ID}')
Assert that all the acquisitions need to have the reference acquisitions channels
dat_acs[V.COL_VALIDAC] = dat_acs[V.COL_IMCAC].map(lambda ac: set(ref_ac.channel_metals).issubset(ac.channel_metals))
# filter for valid acquisitions
dat = (dat_acs
.query(f'{V.COL_VALIDAC}==True')
.merge(dat_acmeta)
.merge(dat_panometa)
)
# generate the images
imgs = [get_img_from_imcac(ac, metals=metals) for ac in dat[V.COL_IMCAC].values]
# create labels based on metadata
labels = dat.apply(lambda row: f'{row[V.COL_ACSESSION].split("_")[1]}\n P: {row[V.COL_PANORAMA]} \n A: {row[V.COL_ACQUISITION]}', axis=1)
bbwidgets.view_multichannel(imgs, image_names=labels, channel_names=channel_labels)
Show only acquisitions from a certain site
site = ['Site4']
# filter for valid acquisitions
dat = (dat_acs
.query(f'{V.COL_VALIDAC}==True')
.merge(dat_acmeta)
.merge(dat_panometa)
.query(f'{V.COL_PANORAMA} == {site}')
)
# generate the images
imgs = [get_img_from_imcac(ac, metals=metals) for ac in dat[V.COL_IMCAC].values]
# create labels based on metadata
labels = dat.apply(lambda row: f'{row[V.COL_ACSESSION].split("_")[1]}\n P: {row[V.COL_PANORAMA]} \n A: {row[V.COL_ACQUISITION]}', axis=1)
bbwidgets.view_multichannel(imgs, image_names=labels, channel_names=channel_labels)